#-*- coding: utf-8 -*-
import httplib
import logging
import traceback
import threading
from SocketServer import ThreadingTCPServer
from BaseHTTPServer import BaseHTTPRequestHandler

from selenose.consts import LOGGER
from selenose.tools import is_26_plus
from selenose.excepts import ServerError

# Get a logger
logger =  logging.getLogger('%s.%s' % (LOGGER, __name__))

class SelenoseHTTPServer(ThreadingTCPServer):

    def __init__(self, host, port, grid, djangos):
        ThreadingTCPServer.__init__(self, (host, port), SelenoseHTTPRequestHandler)
        self.host = host
        self.port = port
        self.grid = grid
        self.djangos = djangos
        self.serve = False
        self.thread = None

    def geturl(self):
        return '%s:%s' % (self.host, self.port)

    def serve_forever(self):
        self.serve = True
        if is_26_plus():
            ThreadingTCPServer.serve_forever(self)
        else:
            while self.serve:
                self.handle_request()

    def shutdown(self):
        self.serve = False
        if is_26_plus():
            ThreadingTCPServer.shutdown(self)
        else:
            conn = httplib.HTTPConnection(self.geturl())
            conn.request('POST', '/shutdown')
            conn.getresponse()
            conn.close()
            
    def start(self):
        if not self.serve:
            self.thread = threading.Thread(target=self.serve_forever)
            self.thread.start()
    
    def stop(self):
        if self.serve:
            self.shutdown()
            self.thread.join()

class SelenoseHTTPRequestHandler(BaseHTTPRequestHandler):
    
    def do_POST(self):
        grid = self.server.grid
        djangos = self.server.djangos
        logger.debug('server process %s' % self.path)
        try:
            if self.path == '/start':
                fixtures = self.pythonize()
                djan = djangos.get()
                djan.flashback()
                djan.loaddata(fixtures=fixtures)
                djan.start()
                data = {'id'       : djan.did,
                        'django'   : djan.geturl(),
                        'host'     : grid.hub.host,
                        'port'     : grid.hub.port,
                        'databases': djan.databases,
                        'log'      : djan.log.name, }
                self.jsonize(data)
            elif self.path == '/stop':
                djan = djangos.getid(self.pythonize())
                djan.stop()
                djangos.put(djan)
                self.send_response(200)
            elif self.path == '/shutdown':
                self.send_response(200)
            else:
                raise ServerError('no service for %s' % self.path)
        except BaseException:
            self.send_error(500, traceback.format_exc())

    def jsonize(self, data):
        from django.utils import simplejson
        jdata = simplejson.dumps(data)
        self.send_response(200)
        self.send_header('Content-Type', 'text/json')
        self.send_header('Content-Length', len(jdata))
        self.end_headers()
        logger.info('server send %s' % data)
        self.wfile.write(jdata)
        self.wfile.flush()
    
    def pythonize(self):
        from django.utils import simplejson
        length = self.headers.get('content-length')
        if length is None:
            raise ServerError('content length not specified')
        jdata = self.rfile.read(int(length))
        logger.info('server received %s' % jdata)
        return simplejson.loads(jdata)
    
def server_start(host, port, grid, djangos):
    server = SelenoseHTTPServer(host, port, grid, djangos)
    server.start()
    return server

def server_stop(server):
    server.stop()
